﻿using D.B.Data.API.Applications.Command.LeaveCommand;
using D.B.Data.Domain;
using D.B.Data.Domain.DTO.Output;
using D.B.Data.Domain.Enums;
using D.B.Data.ErrorCode;
using D.B.Data.Infrastructuse;
using MediatR;
using Microsoft.EntityFrameworkCore;
using static D.B.Data.API.Applications.CommandHandler.LeaveCommandHandler.LeaveTableCommandHandler;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace D.B.Data.API.Applications.CommandHandler.LeaveCommandHandler
{
    public class LeaveTableCommandHandler : IRequestHandler<LeaveTableCommand, APIPaging<UserLeaveSummaryDto>>
    {
        private readonly IBaseRepository<WorkflowModel> baseRepository;

        public LeaveTableCommandHandler(IBaseRepository<WorkflowModel> baseRepository)
        {
            this.baseRepository = baseRepository;
        }

        public Task<APIPaging<UserLeaveSummaryDto>> Handle(LeaveTableCommand request, CancellationToken cancellationToken)
        {

            // 如果没有指定年份，使用当前年份
            var targetYear = request.year ?? DateTime.Now.Year;

            var res= baseRepository.GetAll().AsNoTracking().Where(s=>!s.IsDel&&s.State&&s.LeaveTIme.Year== targetYear);

            if(!string.IsNullOrEmpty(request.UserName))
            {
                res = res.Where(s => s.UserName.Contains(request.UserName));
            }

            List<UserLeaveSummaryDto> dTO = new List<UserLeaveSummaryDto>();


           

            // 第一步：获取所有用户
            var users = res
                .Where(s=>!s.IsDel)
                .Select(w => new { w.UserId, w.UserName })
                .Distinct()
                .OrderBy(u => u.UserName)
                .ToList();

            // 第二步：为每个用户获取月度汇总
            var result = new List<UserLeaveSummaryDto>();

            foreach (var user in users)
            {
                // 获取该用户实际有数据的月份
                var actualData = res
                    .Where(w => w.UserName == user.UserName &&(!request.year.HasValue || w.LeaveTIme.Year == request.year.Value))
                    .GroupBy(w => new { w.LeaveTIme.Year, w.LeaveTIme.Month })
                    .Select(g => new MonthlyLeaveSummaryDto
                    {
                        Year = g.Key.Year,
                        Month = g.Key.Month,
                        TotalLeaveHours = g.Sum(w => w.SumTime)
                    })
                    .ToList();

                // 生成完整月份列表并与实际数据左连接
                var allMonths = GenerateAllMonths(targetYear)
                    .Select(month => new MonthlyLeaveSummaryDto
                    {
                        Year = month.Year,
                        Month = month.Month,
                        TotalLeaveHours = actualData
                            .FirstOrDefault(d => d.Year == month.Year && d.Month == month.Month)?
                            .TotalLeaveHours ?? 0
                    })
                    .OrderBy(m => m.Year)
                    .ThenBy(m => m.Month)
                    .ToList();

                result.Add(new UserLeaveSummaryDto
                {
                    UserId = user.UserId,
                    UserName = user.UserName,
                    MonthlySummaries = allMonths
                });
            }
           


            APIPaging<UserLeaveSummaryDto> paging = new APIPaging<UserLeaveSummaryDto>()
            {
                PageData = result
            };

            return Task.FromResult(paging); 

            
        }


        public class UserLeaveSummaryDto
        {
            public long UserId { get; set; }
            public string UserName { get; set; }
            public List<MonthlyLeaveSummaryDto> MonthlySummaries { get; set; } = new();
        }

        public class MonthlyLeaveSummaryDto
        {
            public int Year { get; set; }
            public int Month { get; set; }
            public int TotalLeaveHours { get; set; }
        }


        private static List<MonthInfo> GenerateAllMonths(int year)
        {
            return Enumerable.Range(1, 12)
                .Select(month => new MonthInfo { Year = year, Month = month })
                .ToList();
        }

        private class MonthInfo
        {
            public int Year { get; set; }
            public int Month { get; set; }
        }
    }
}
